package com.personal.common.util;

import java.math.BigDecimal;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang.StringUtils;

public class NumberUtil {

	private static final int DIVISION_PRECISION = 10;

	private NumberUtil() {

	}

	/**
	 * 
	 * @param b1
	 * @param b2
	 * @return
	 */
	public static BigDecimal add(BigDecimal b1, BigDecimal b2) {

		return b1.add(b2);
	}

	/**
	 * 
	 * @param b1
	 * @param b2
	 * @return
	 */
	public static BigDecimal subtract(BigDecimal b1, BigDecimal b2) {

		return b1.subtract(b2);
	}

	/**
	 * 
	 * @param b1
	 * @param b2
	 * @return
	 */
	public static BigDecimal multiply(BigDecimal b1, BigDecimal b2) {

		return b1.multiply(b2);
	}

	/**
	 * 
	 * @param v1
	 * @param v2
	 * @return
	 */
	public static BigDecimal divide(BigDecimal b1, BigDecimal b2) {

		return divide(b1, b2, DIVISION_PRECISION);
	}

	/**
	 * 
	 * @param b1
	 * @param b2
	 * @param precision
	 * @return }
	 */
	public static BigDecimal divide(BigDecimal b1, BigDecimal b2, int precision) {

		if (precision < 0) {
			// throw new IllegalArgumentException("The precision must be a
			// positive integer or zero");
			throw new IllegalArgumentException("㾫ȱǴ");
		}
		return b1.divide(b2, precision, BigDecimal.ROUND_UP);
	}

	/**
	 * @param b
	 * @param precision
	 * @return
	 */
	public static BigDecimal round(BigDecimal b, int precision) {

		if (precision < 0) {
			// throw new IllegalArgumentException("The precision must be a
			// positive integer or zero");
			throw new IllegalArgumentException("㾫ȱǴ");
		}
		BigDecimal one = new BigDecimal("1");
		return b.divide(one, precision, BigDecimal.ROUND_HALF_UP);
	}

	public static BigDecimal round(String b, int precision) {

		if (precision < 0) {
			// throw new IllegalArgumentException("The precision must be a
			// positive integer or zero");
			throw new IllegalArgumentException("㾫ȱǴ");
		}
		if (StringUtils.isBlank(b)) {
			return new BigDecimal(0);
		}
		BigDecimal one = new BigDecimal("1");
		return new BigDecimal(b).divide(one, precision, BigDecimal.ROUND_HALF_UP);
	}

	/**
	 * 
	 * @param v1
	 * @param v2
	 * @return ĺ
	 */
	public static double add(double v1, double v2) {

		BigDecimal b1 = new BigDecimal(Double.toString(v1));
		BigDecimal b2 = new BigDecimal(Double.toString(v2));
		return b1.add(b2).doubleValue();
	}

	/**
	 * 
	 * @param v1
	 * @param v2
	 * @return
	 */
	public static double subtract(double v1, double v2) {

		BigDecimal b1 = new BigDecimal(Double.toString(v1));
		BigDecimal b2 = new BigDecimal(Double.toString(v2));
		return b1.subtract(b2).doubleValue();
	}

	/**
	 * 
	 * @param v1
	 * @param v2
	 * @return
	 */
	public static double multiply(double v1, double v2) {

		BigDecimal b1 = new BigDecimal(Double.toString(v1));
		BigDecimal b2 = new BigDecimal(Double.toString(v2));
		return b1.multiply(b2).doubleValue();
	}

	/**
	 * 
	 * @param v1
	 * @param v2
	 * @return
	 */
	public static double divide(double v1, double v2) {

		return divide(v1, v2, DIVISION_PRECISION);
	}

	/**
	 * @param v1
	 * @param v2
	 * @param precision
	 * @return }
	 */
	public static double divide(double v1, double v2, int precision) {

		if (precision < 0) {
			// throw new IllegalArgumentException("The precision must be a
			// positive integer or zero");
			throw new IllegalArgumentException("㾫ȱǴ");
		}
		BigDecimal b1 = new BigDecimal(Double.toString(v1));
		BigDecimal b2 = new BigDecimal(Double.toString(v2));
		return b1.divide(b2, precision, BigDecimal.ROUND_UP).doubleValue();
	}

	/**
	 * 不四舍五入
	 * 
	 * @param value
	 *            值
	 * @param precision
	 *            位数
	 * @return Ľ
	 */
	public static BigDecimal roundNoCut(double value, int precision) {

		if (precision < 0) {
			// throw new IllegalArgumentException("The precision must be a
			// positive integer or zero");
			throw new IllegalArgumentException("㾫ȱǴ");
		}
		BigDecimal b = new BigDecimal(value);
		return b.setScale(precision, 2);
	}

	/**
	 * 保留精确度
	 * 
	 * @param value
	 *            值
	 * @param precision
	 *            位数
	 * @return Ľ
	 */
	public static BigDecimal round(double value, int precision) {

		if (precision < 0) {
			// throw new IllegalArgumentException("The precision must be a
			// positive integer or zero");
			throw new IllegalArgumentException("㾫ȱǴ");
		}
		BigDecimal b = new BigDecimal(Double.toString(value));
		BigDecimal one = new BigDecimal("1");
		return b.divide(one, precision, BigDecimal.ROUND_UP);
	}

	/**
	 * 批价中的金额*10^5后转为Long保存到数据库
	 * 
	 * @param value
	 * @return
	 */
	public static Long getLong(BigDecimal value) {

		Long longVal = 0L;
		try {
			BigDecimal val = round(value, 5);
			longVal = new BigDecimal(val.doubleValue() * 100000).longValue();
		} catch (NumberFormatException ex) {
			return 0L;
		}
		return longVal;
	}

	public static Long toLong(String str) {

		if (StringUtils.isNotBlank(str)) {
			str = str.trim();
		} else {
			return 0L;
		}

		Long i = 0L;

		try {
			i = Long.parseLong(str);
		} catch (NumberFormatException ex) {
			i = 0L;
		}
		return i;
	}

	public static Long toLong(String str, Long retLong) {

		if (StringUtils.isNotBlank(str)) {
			str = str.trim();
		} else {
			return retLong;
		}

		Long i = 0L;

		try {
			i = Long.parseLong(str);
		} catch (NumberFormatException ex) {
			i = retLong;
		}
		return i;
	}

	public static Double toDouble(String str) {

		if (StringUtils.isNotBlank(str)) {
			str = str.trim();
		} else {
			return 0D;
		}

		Double i = 0D;

		try {
			i = Double.parseDouble(str);
		} catch (NumberFormatException ex) {
			i = 0.0D;
		}
		return i;
	}

	public static Integer toInt(String str) {

		if (StringUtils.isNotBlank(str)) {
			str = str.trim();
		} else {
			return 0;
		}

		Integer i = 0;

		try {
			i = Integer.parseInt(str);
		} catch (NumberFormatException ex) {
			i = 0;
		}
		return i;
	}

	public static Double roundToDouble(Double num, Integer i) {

		java.math.BigDecimal f = new java.math.BigDecimal(num);// 小数点后保留2位，4舍5入
		f = f.setScale(i, java.math.BigDecimal.ROUND_HALF_UP);
		return f.doubleValue();
	}

	public static boolean isNumeric(String str) {
		if (null == str) {
			return false;
		}
		Pattern pattern = Pattern.compile("-?[0-9]+.?[0-9]+");
		Matcher isNum = pattern.matcher(str);
		if (!isNum.matches()) {
			return false;
		}
		return true;
	}

	/**
	 * 
	 * @description:TODO(简要描述此方法的作用)
	 * @author:     weijintong
	 * @date:       2015年5月23日 下午12:07:18
	 * @version:	v1.0 
	 */
	public static Number transferNumberValue(Object obj) {
		Number num = 0;
		if (obj instanceof Number) {
			num = (Number) obj;
		} else if (obj instanceof String) {
			num = Double.parseDouble(obj.toString());
		}
		return num;
	}
}